package com.platform.usercenter.utils;

import com.platform.usercenter.domain.vo.SysOrganizationVO;
import com.platform.usercenter.service.TreeAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 构建树结构工具类
 * @Author: cl
 * @Date: 2024-11-06 09:22
 **/
@Slf4j
public class TreeAdapterUtil {

    private TreeAdapterUtil() {
    }

    /**
     * 构建前端所需要树结构
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    public static <T> List<T> buildTree(List<? extends TreeAdapter> menus, Class<T> clazz, List<? extends TreeAdapter> parentList) {
        if (CollectionUtils.isEmpty(menus)) {
            return Lists.newArrayList();
        }
        if (CollectionUtils.isEmpty(parentList)) {
            parentList = menus.stream().filter(item -> item.getTreeParentId() == 0L).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(parentList)) {
                // 将menus中的元素转换为T类型并返回新的List<T>
                return menus.stream()
                        .map(clazz::cast)
                        .collect(Collectors.toList());
            }
        }

        List<T> returnList = new ArrayList<>();
        for (TreeAdapter menu : parentList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            recursionFn(menus, menu, clazz);
            returnList.add(clazz.cast(menu));
        }
        return returnList;
    }


    private static <T> void recursionFnWithUsedSet(List<? extends TreeAdapter> list,
                                                   TreeAdapter item, Class<T> clazz,
                                                   Set<TreeAdapter> usedSet) {
        // 得到子节点列表
        List<TreeAdapter> childList = getChildList(list, item);
        if (!CollectionUtils.isEmpty(childList)) {
            usedSet.addAll(childList);
        }
        item.setTreeChildren(childList, clazz);
        for (TreeAdapter tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild, clazz);
            }
        }
    }

    /**
     * 构建前端所需要树结构 没有父级的直接拼接在最后
     *
     * @param menus 菜单列表
     * @return 树结构列表
     */
    public static <T> List<T> buildTreeWithoutRootAppendList(List<? extends TreeAdapter> menus, Class<T> clazz, List<? extends TreeAdapter> parentList) {
        if (CollectionUtils.isEmpty(menus)) {
            return Lists.newArrayList();
        }
        List<TreeAdapter> notParentList = menus.stream().filter(item -> item.getTreeParentId() != 0L).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(parentList)) {
            parentList = menus.stream().filter(item -> item.getTreeParentId() == 0L).collect(Collectors.toList());
            log.info("存顶级在父节点");
            if (CollectionUtils.isEmpty(parentList)) {
                // 将menus中的元素转换为T类型并返回新的List<T>
                return menus.stream()
                        .map(clazz::cast)
                        .collect(Collectors.toList());
            }
        }
        Set<TreeAdapter> usedSet = new HashSet<>();
        List<T> returnList = new ArrayList<>();
        for (TreeAdapter menu : parentList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            recursionFnWithUsedSet(menus, menu, clazz, usedSet);
            returnList.add(clazz.cast(menu));
        }
        // 排除在树中的item 不在树中的item直接加到第一级
        if (!CollectionUtils.isEmpty(notParentList)) {
            List<TreeAdapter> notRelationList = Lists.newArrayList();
            for (TreeAdapter treeAdapter : notParentList) {
                if (!usedSet.contains(treeAdapter)) {
                    notRelationList.add(treeAdapter);
                }
            }
            if (!CollectionUtils.isEmpty(notRelationList)) {
                List<TreeAdapter> parent = findParent(notRelationList);
                if (!CollectionUtils.isEmpty(parent)) {
                    for (TreeAdapter treeAdapter : parent) {
                        recursionFn(notRelationList, treeAdapter, clazz);
                        returnList.add(clazz.cast(treeAdapter));
                    }
                }
            }
        }
        returnList.sort(Comparator.comparing(o -> ((TreeAdapter) o).getTreeCurrentId()));
        return returnList;
    }

    private static List<TreeAdapter> findParent(List<TreeAdapter> notRelationList) {
        Set<Long> parentIds = notRelationList.stream().map(TreeAdapter::getTreeParentId).collect(Collectors.toSet());
        for (Long parentId : parentIds) {
            List<TreeAdapter> parentList = notRelationList.stream()
                    .filter(item -> item.getTreeCurrentId().equals(parentId))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(parentList)) {
                return parentList;
            }
        }
        return null;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    public static <T> void recursionFn(List<? extends TreeAdapter> list, TreeAdapter t, Class<T> clazz) {
        // 得到子节点列表
        List<TreeAdapter> childList = getChildList(list, t);
        t.setTreeChildren(childList, clazz);
        for (TreeAdapter tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild, clazz);
            }
        }
    }

    /**
     * 判断是否有子节点
     */
    private static boolean hasChild(List<? extends TreeAdapter> list, TreeAdapter t) {
        return !getChildList(list, t).isEmpty();
    }


    /**
     * 得到子节点列表
     */
    private static List<TreeAdapter> getChildList(List<? extends TreeAdapter> list, TreeAdapter t) {
        List<TreeAdapter> tlist = new ArrayList<>();
        for (TreeAdapter n : list) {
            if (n.getTreeParentId().longValue() == t.getTreeCurrentId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }


}
